﻿using System;
using JamesZhao.Engine.GameComponents;
using SlimMath;

namespace JamesZhao.Engine.GameObjects
{
    public class TransformComponent : GameComponent
    {
        private static readonly Vector3 ScalingCenter = Vector3.Zero;
        private static readonly Quaternion ScalingRotation = Quaternion.Identity;
        private static readonly Vector3 RotationCenter = Vector3.Zero;

        public TransformComponent(GameObject owner) : base(owner)
        {
            LocalPosition = Vector3.Zero;
            LocalRotation = Quaternion.Identity;
            LocalScale = Vector3.One;
        }

        public TransformComponent ParentTransform { get; set; }

        public Vector3 LocalPosition { get; set; }

        public Quaternion LocalRotation { get; set; }

        public Vector3 LocalScale { get; set; }

        public Vector3 WorldPosition
        {
            get { return LocalToWorldMatrix.TranslationVector; }
        }

        public Quaternion WorldRotation
        {
            get { return Quaternion.RotationMatrix(LocalToWorldMatrix); }
        }

        public Vector3 WorldScale
        {
            get { return LocalToWorldMatrix.ScaleVector; }
        }

        public Matrix LocalToWorldMatrix
        {
            get
            {
                Matrix parentTransformMatrix = ParentTransform != null
                                                   ? ParentTransform.LocalToWorldMatrix
                                                   : Matrix.Identity;
                return parentTransformMatrix*
                       Matrix.Transformation(ScalingCenter, ScalingRotation, LocalScale, RotationCenter,
                                             LocalRotation, LocalPosition);
            }
        }

        public Vector3 Up
        {
            get { return Vector3.Transform(Vector3.UnitY, WorldRotation); }
        }

        public Vector3 Forward
        {
            get { return Vector3.Transform(Vector3.UnitZ, WorldRotation); }
        }

        public Vector3 Left
        {
            get { return Vector3.Transform(Vector3.UnitX, WorldRotation); }
        }

        public void LookAt(GameObject target)
        {
            LookAt(target.Transform);
        }

        public void LookAt(TransformComponent target)
        {
            throw new NotImplementedException();
        }
    }
}